<template>
  <div>
    <canvas
      :width="canvasWidth"
      :height="canvasHeight"
      id="canvas"
      ref="canvasElement"
    ></canvas>
  </div>
</template>

<script lang="ts" setup>
import adapter from "webrtc-adapter";
import jsQR from "jsqr";
import { onUnmounted, ref } from "vue";
import { clearTimeout } from "timers";
const videoRef = document.createElement("video");
const canvasElement = ref<HTMLCanvasElement>();
let canvasWidth = ref(48);
let canvasHeight = ref(50);
const canvasElement2 = document.createElement("canvas");
let canvas2d2;
let canvas2d;
const emits = defineEmits(["scan-success"]);
const openScan = async () => {
  const videoParam = { video: true };
  const stream = await navigator.mediaDevices.getUserMedia(videoParam);
  videoRef.srcObject = stream;
  videoRef.setAttribute("playsinline", "true");
  videoRef.play();
  videoRef.onloadeddata = () => {
    requestAnimationFrame(tick);
  };
};
let timer: any = null;
const tick = (time) => {
  try {
    if (videoRef.readyState === videoRef.HAVE_ENOUGH_DATA) {
      // canvasHeight.value = videoRef.videoHeight;
      // canvasWidth.value = videoRef.videoWidth;
      canvasElement2.height = videoRef.videoHeight;
      canvasElement2.width = videoRef.videoWidth;
      !canvas2d2 &&
        (canvas2d2 = canvasElement2?.getContext("2d", {
          willReadFrequently: true,
        }));
      !canvas2d &&
        (canvas2d = canvasElement.value?.getContext("2d", {
          willReadFrequently: true,
        }));
      canvas2d.drawImage(
        videoRef,
        0,
        0,
        canvasElement.value?.width,
        canvasElement.value?.height
      );
      canvas2d2.drawImage(
        videoRef,
        0,
        0,
        canvasElement2.width,
        canvasElement2.height
      );
      var imageData = canvas2d2.getImageData(
        0,
        0,
        canvasElement2.width,
        canvasElement2.height
      );
      var code = jsQR(imageData.data, imageData.width, imageData.height, {
        inversionAttempts: "dontInvert",
      });
      if (code) {
        emits("scan-success", code.data);
        clearTimer();
        timer = setTimeout(() => {
          requestAnimationFrame(tick);
        }, 2000);
      } else {
        requestAnimationFrame(tick);
      }
    } else {
      requestAnimationFrame(tick);
    }
  } catch (e) {
    requestAnimationFrame(tick);
  }
};
const clearTimer = () => {
  if (timer) {
    clearTimeout(timer);
    timer = null;
  }
};
onUnmounted(() => {
  clearTimer();
}),
  openScan();
</script>
<style scoped lang="scss"></style>
